package cc.rengu.redp.system.controller;

import cc.rengu.redp.bizimpl.upmp.service.IUpmpSysParamService;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpUserInfoService;
import cc.rengu.redp.bizimpl.upmp.vo.UpmpUserInfoVO;
import cc.rengu.redp.bizimpl.utils.CommonUtils;
import cc.rengu.redp.common.annotation.Log;
import cc.rengu.redp.common.controller.BaseController;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.domain.RedpResponse;
import cc.rengu.redp.common.utils.EasyExcelUtil;
import cc.rengu.redp.common.utils.HashUtil;
import cc.rengu.redp.common.utils.RedpUtil;
import cc.rengu.redp.system.domain.DictRsVo;
import cc.rengu.redp.system.domain.Role;
import cc.rengu.redp.system.domain.User;
import cc.rengu.redp.system.domain.UserConfig;
import cc.rengu.redp.system.service.RoleService;
import cc.rengu.redp.system.service.UserConfigService;
import cc.rengu.redp.system.service.UserService;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Validated
@RestController
@RequestMapping("user")
public class UserController extends BaseController {

    @Autowired
    private UserService userService;
    @Autowired
    private UserConfigService userConfigService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private IUpmpSysParamService upmpSysParamService;
    @Autowired
    private IUpmpUserInfoService upmpUserService;

    @GetMapping("check/{username}")
    public boolean checkUserName(@NotBlank(message = "{required}") @PathVariable String username) {
        return this.userService.findByName(username) == null;
    }

    @GetMapping("/{username}")
    public User detail(@NotBlank(message = "{required}") @PathVariable String username) {
        if (username.equals(RedpUtil.getCurrentUser().getUsername())) {
            User user = this.userService.findByName(username);
            //修复用户修改自己的个人信息第二次提示roleId不能为空
            List<Role> roles = roleService.findUserRole(username);
            List<Long> roleIds = roles.stream().map(role -> role.getRoleId()).collect(Collectors.toList());
            String roleIdStr = StringUtils.join(roleIds.toArray(new Long[roleIds.size()]), ",");
            user.setRoleId(roleIdStr);
            return user;
        }

        return null;
    }

    @GetMapping
    @RequiresPermissions("user:view")
    public Map<String, Object> userList(QueryRequest queryRequest, User user) {
        return getDataTable(userService.findUserDetail(user, queryRequest));
    }

    @GetMapping("getAllUsers")
    public List<DictRsVo> getAllUsers() {
        List<User> users = userService.getAllUsers();
        List<DictRsVo> dictRsVos = new ArrayList<>();
        users.forEach(user -> dictRsVos.add(new DictRsVo(user.getUsername(), user.getUsername())));
        return dictRsVos;
    }

    @Log("新增用户")
    @PostMapping
    @RequiresPermissions("user:add")
    public RedpResponse addUser(@Valid User user) {
        try {
            this.userService.createUser(user);
        } catch (Exception e) {
            String message = "新增用户失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }

        return RedpResponse.getInstance().success().message("新增用户成功");
    }

    @Log("修改用户")
    @PutMapping
    @RequiresPermissions("user:update")
    public RedpResponse updateUser(@Valid User user) {
        try {
            this.userService.updateUser(user);
        } catch (Exception e) {
            String message = "修改用户失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }

        return RedpResponse.getInstance().success().message("修改用户成功");
    }

    @Log("删除用户")
    @DeleteMapping("/{userIds}")
    @RequiresPermissions("user:delete")
    public RedpResponse deleteUsers(@NotBlank(message = "{required}") @PathVariable String userIds) {
        try {
            String[] ids = userIds.split(StringPool.COMMA);
            this.userService.deleteUsers(ids);
        } catch (Exception e) {
            String message = "删除用户失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }

        return RedpResponse.getInstance().success().message("删除用户成功");
    }

    @Log("更新个人信息")
    @PutMapping("profile")
    public RedpResponse updateProfile(@Valid User user) {
        if (StringUtils.isNotBlank(user.getUsername()) && user.getUsername().equals(RedpUtil.getCurrentUser().getUsername())) {
            try {
                this.userService.updateProfile(user);
            } catch (Exception e) {
                String message = "修改个人信息失败";
                log.error(message, e);
                return RedpResponse.getInstance().failure().message(message);
            }
        } else {
            String message = "修改人与修改目标用户不一致";
            log.error("修改人（{}）与修改目标用户（{}）不一致", RedpUtil.getCurrentUser().getUsername(), user.getUsername());
            return RedpResponse.getInstance().failure().message(message);
        }

        return RedpResponse.getInstance().success().message("更新个人信息成功");
    }

    @Log("修改头像")
    @PutMapping("avatar")
    public RedpResponse updateAvatar(@NotBlank(message = "{required}") String avatar) {
        String userId = CommonUtils.getCurrentUser(upmpSysParamService).getId();
        try {
            this.upmpUserService.updateAvatar(userId, avatar);
        } catch (Exception e) {
            String message = "修改头像失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }

        return RedpResponse.getInstance().success().message("修改头像成功");
    }

    @Log("修改个性化配置")
    @PutMapping("userconfig")
    public RedpResponse updateUserConfig(@Valid UserConfig userConfig) {
        UpmpUserInfoVO upmpUserInfoVO = CommonUtils.getCurrentUser(upmpSysParamService);
        if(upmpUserInfoVO == null) {
            String message = "获取用户失败";
            log.error("目标用户（{}）", userConfig.getUserId());
            return RedpResponse.getInstance().failure().message(message);
        }
        if (userConfig.getUserId() != null && String.valueOf(userConfig.getUserId()).equals(upmpUserInfoVO.getUserId())) {
            try {
                this.userConfigService.update(userConfig);
            } catch (Exception e) {
                String message = "修改个性化配置失败";
                log.error(message, e);
                return RedpResponse.getInstance().failure().message(message);
            }
        } else {
            String message = "修改人与修改目标用户不一致";
            log.error("修改人（{}）与修改目标用户（{}）不一致", upmpUserInfoVO.getUserName(), userConfig.getUserId());
            return RedpResponse.getInstance().failure().message(message);
        }

        return RedpResponse.getInstance().success().message("修改个性化配置成功");
    }

    @GetMapping("password/check")
    public boolean checkPassword(@NotBlank(message = "{required}") String password) {
        String username = RedpUtil.getCurrentUser().getUsername();
        String encryptPassword = HashUtil.encryptGm(username, password);
        User user = userService.findByName(username);
        if (user != null) {
            return StringUtils.equals(user.getPassword(), encryptPassword);
        } else {
            return false;
        }
    }

    @Log("修改密码")
    @PutMapping("password")
    public RedpResponse updatePassword(
            @NotBlank(message = "{required}") String oldPassword,
            @NotBlank(message = "{required}") String newPassword) {
        if (this.checkPassword(oldPassword)) {
            String username = RedpUtil.getCurrentUser().getUsername();
            try {
                userService.updatePassword(username, newPassword);
            } catch (Exception e) {
                String message = "修改密码失败";
                log.error(message, e);
                return RedpResponse.getInstance().failure().message(message);
            }
        } else {
            String message = "修改密码失败";
            log.error(message);
            return RedpResponse.getInstance().failure().message(message);
        }

        return RedpResponse.getInstance().success().message("修改密码成功");
    }

    @Log("重置用户密码")
    @PutMapping("password/reset")
    @RequiresPermissions("user:reset")
    public RedpResponse resetPassword(@NotBlank(message = "{required}") String usernames) {
        try {
            String[] usernameArr = usernames.split(StringPool.COMMA);
            this.userService.resetPassword(usernameArr);
        } catch (Exception e) {
            String message = "重置用户密码失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }

        return RedpResponse.getInstance().success().message("重置用户密码成功");
    }

    @Log("导出个人信息")
    @PostMapping("excel")
    @RequiresPermissions("user:export")
    public RedpResponse export(QueryRequest queryRequest, User user, HttpServletResponse response) {
        try {
            List<User> users = this.userService.findUserDetail(user, queryRequest).getRecords();
            EasyExcelUtil.export(response, users, "用户信息表");
        } catch (Exception e) {
            String message = "导出Excel失败";
            log.error(message, e);
            return RedpResponse.getInstance().failure().message(message);
        }

        return RedpResponse.getInstance().success().message("导出Excel成功");
    }
}
